#ifndef __CARIOU_LINARD_TEXTURE_HH__
#define __CARIOU_LINARD_TEXTURE_HH__

#include "image.h"
#include "maths3d.h"

class Texture
{

    protected:

    public:

        Texture() {}
        virtual ~Texture() {}
        Texture(const Texture &) {}
        Texture& operator=(const Texture &) {return *this;}

        virtual void getColorAt(double &, double &, Color &)=0;
        virtual bool isShared() const { return false; }
};

class Damier : public Texture
{
    protected:

        Color  c1;
        Color  c2;

    public:

    Damier() : c1(0.0,0.0,0.0), c2(1.0,1.0,1.0)
    {
    }

    virtual ~Damier() {}
    Damier(const Damier &) {}
    Damier& operator=(const Damier &) {return *this;}


    Damier(const Color &_c1, const Color &_c2) : c1(_c1), c2(_c2)
    {

    }

    virtual void getColorAt(double &x, double &y, Color &c)
    {
        if( x > 0.0 ) while( x > 1.0 ) x--;
        else          while( x < 0.0 ) x++;
        if( y > 0.0 ) while( y > 1.0 ) y--;
        else          while( y < 0.0 ) y++;
        c = c1;
        if( (x < 0.5) && (y < 0.5) )
            c = c2;
        else if( (x >=0.5) && ( y >= 0.5) )
            c = c2;
    }
};

class FTexture : public Texture
{
    protected:

        Image image;

    public:

    FTexture() : image()
    {
    }

    virtual ~FTexture() {}
    FTexture(const FTexture &) {}
    FTexture& operator=(const FTexture &) {return *this;}

    FTexture(char * file) : image(file)
    {

    }

    virtual void getColorAt(double &x, double &y, Color &c)
    {
        if( x > 0.0 ) while( x > 1.0 ) x--;
        else          while( x < 0.0 ) x++;
        if( y > 0.0 ) while( y > 1.0 ) y--;
        else          while( y < 0.0 ) y++;

        int X((int)(x * image.getWidth())), Y((int)(y * image.getHeight()));
        unsigned char * ptr = image.getData()+(Y*image.getWidth()+X)*3;
        c = Color((*ptr)/255.0,*(ptr+1)/255.0,*(ptr+2)/255.0);
    }
    virtual bool isShared() const { return true; }
};

#endif
